home *** CD-ROM | disk | FTP | other *** search
/ Your Choice 3 / Your Choice Software Collection 3.iso / prgmming / xlib41 / pmio.inc < prev    next >
Text File  |  1994-03-01  |  33KB  |  735 lines

  1. ;                  Protected-Mode Input/Output Procedures.
  2. ;                               Version 1.1
  3. ;
  4. ;   All PMIO procedures assume that the code is resident in a 32-bit segment.
  5. ;The flat-data model is also assumed, that is, DS = FLATDSEL.  If the latter
  6. ;assumption is unacceptable, then modify the code to load DS at the beginning of
  7. ;the procedures.  A full explanation of each IO procedure is provided above the
  8. ;procedure.  The following is a brief summary:
  9. ;
  10. ;Screen Procedures:
  11. ;
  12. ;   The screen procedures always print at the recorded BIOS cursor position and
  13. ;update the BIOS position after printing; however, they do not adjust the video
  14. ;hardware to actually relocate the cursor on the screen.  Call UPDATECSR for
  15. ;this purpose.
  16. ;   The screen procedures avoid all calls to DOS and BIOS.  Therefore, they
  17. ;should function properly within interrupt handlers.
  18. ;   The screen address is assumed to be B8000H, which will be the case for
  19. ;color monitors.  For monochrome monitors, set SCRNBASEADR to B0000H.
  20. ;
  21. ;Procedure     Description
  22. ;PCH           Print ASCII character in AL
  23. ;CRLF          Issue carriage return and line feed
  24. ;SCRLUP        Scoll screen up
  25. ;SPC           Print AL spaces
  26. ;CLS           Clear screen
  27. ;PSTR          Print zero terminated ASCII string at ES:EBX
  28. ;PCSSTR        Print zero terminated ASCII string at CS:EBX
  29. ;PHW           Print WORD in AX as hexadecimal
  30. ;PHD           Print DWORD in EAX as hexadecimal
  31. ;PUW           Print unsigned WORD in AX as decimal
  32. ;PUD           Print unsigned DWORD in EAX as decimal
  33. ;PSW           Print signed WORD in AX as decimal
  34. ;PSD           Print signed DWORD in EAX as decimal
  35. ;FPST          Print ST of FPU using format in AX.  AH = characters to left of
  36. ;              decimal.  AL = characters to right of decimal.
  37. ;
  38. ;Keyboard Procedures:
  39. ;
  40. ;Procedure     Description
  41. ;GETCH         Get character from keyboard in AX.  AL = either ASCII code or
  42. ;              scan code.  If sign bit of AH is set, then scan code.  Other bits
  43. ;              in AH define the state of shift and toggle keys (see procedure
  44. ;              for detail).  Character is not echoed.
  45. ;SETCSRPOS     Set cursor position.  Call with (AH,AL) = (row,column).  Rows
  46. ;              range from zero (top) to 24 (bottom).  Columns range from zero
  47. ;              (left) to 79 (right).
  48. ;GETCSRPOS     Get cursor position in AX.  (AH,AL) = (row,column).
  49. ;UPDATECSR     Physically relocate cursor on screen to current BIOS coordinates.
  50. ;SETCSRTYPE    Set cursor type.  Call with AL = 0 for underline, or 1 for block.
  51. ;              Call with sign bit of AL set to disable the cursor.
  52. ;SETCSR        Set cursor position and type.  Call with position in DX and type
  53. ;              in CX.  CH = start scan line, and CL = end scan line.  Scan lines
  54. ;              range from 0 (top) to 7 (bottom).
  55. ;GETCSR        Get cursor position/type in DX/CX (CH/CL = start/end scan line).
  56. ;
  57. ;Speaker Procedures:
  58. ;
  59. ;Procedure     Description
  60. ;BEEP          Produce beep through speaker.
  61.  
  62. ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  63. ;TASM Modifications
  64. ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  65.  
  66. ;   TASM users should set TASMMODE below to true.  These modifications were
  67. ;tested with TASM 4.0.
  68.  
  69. TRUE           =              1
  70. FALSE          =              0
  71.  
  72. TASMMODE       =              FALSE
  73.  
  74.                IF TASMMODE
  75.  
  76.                MASM51
  77.                QUIRKS
  78.                SMART
  79.                NOJUMPS
  80.                LARGESTACK
  81.  
  82. PUSHW          MACRO IMMEDIATE16:REST                       ;PUSH immediate 16-bit data
  83.                IF (@WordSize EQ 4)
  84.                DB             66H
  85.                ENDIF
  86.                DB             68H
  87.                DW             IMMEDIATE16
  88.                ENDM
  89.  
  90. PUSHD          MACRO IMMEDIATE32:REST                       ;PUSH immediate 32-bit data
  91.                IF (@WordSize EQ 2)
  92.                DB             66H
  93.                ENDIF
  94.                DB             68H
  95.                DD             IMMEDIATE32
  96.                ENDM
  97.  
  98.                ENDIF
  99.  
  100. ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  101. ;Local Data and Constants
  102. ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  103.  
  104.                ALIGN          4
  105. SCRNBASEADR    DD             000B8000H                     ;Screen address
  106. CURPOSADR      EQU            00000450H                     ;BIOS address containing cursor position
  107. TICKCNTADR     EQU            0000046CH                     ;BIOS address containing timer-tick counter
  108.  
  109. ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  110. ;Screen Routines
  111. ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  112.  
  113. ;Print ASCII code in AL at cursor.
  114. PCH            PROC NEAR
  115.                PUSH           EBX
  116.                PUSH           EDX
  117.                MOV            EDX,DWORD PTR DS:[CURPOSADR]  ;Cursor (row,col) in (DH,DL)
  118.                PUSH           EDX                           ;Push cursor position
  119.                XOR            EBX,EBX
  120.                MOV            BL,DH
  121.                SHL            EBX,5                         ;Multiply row by 160
  122.                LEA            EBX,[EBX+4*EBX]               ;160 = 32 + 4 * 32
  123.                AND            EDX,0FFH                      ;Clear all but column
  124.                LEA            EBX,[EBX+2*EDX]
  125.                ADD            EBX,CS:SCRNBASEADR
  126.                POP            EDX                           ;POP cursor position
  127.                MOV            [EBX],AL
  128.                INC            DL                            ;Increment column
  129.                CMP            DL,79
  130.                JBE            RCDCURSOR
  131.                XOR            DL,DL                         ;Move to zero column of next row
  132.                INC            DH                            ;Move to next row
  133. RCDCURSOR:     MOV            WORD PTR DS:[CURPOSADR],DX    ;Assume row is valid
  134.                CMP            DH,24
  135.                JA             DOSCROLL
  136. EXIT:          POP            EDX
  137.                POP            EBX
  138.                RET
  139. DOSCROLL:      PUSHD          OFFSET EXIT
  140.                JMP            SCRLUP
  141. PCH            ENDP
  142.  
  143. ;Clear cursor to end of line and issue CRLF.  Scroll up if necessary.
  144. CRLF           PROC NEAR
  145.                PUSH           EAX
  146.                PUSH           EBX
  147.                PUSH           ECX
  148.                MOV            EAX,DWORD PTR DS:[CURPOSADR]
  149.                PUSH           EAX                           ;PUSH cursor position
  150.                XOR            EBX,EBX
  151.                MOV            BL,AH
  152.                SHL            EBX,5                         ;Multiply row by 160
  153.                LEA            EBX,[EBX+4*EBX]               ;160 = 32 + 4 * 32
  154.                AND            EAX,0FFH                      ;Clear all but column
  155.                MOV            CL,80
  156.                SUB            CL,AL                         ;Get number of bytes to clear in CL
  157.                LEA            EBX,[EBX+2*EAX]
  158.                ADD            EBX,CS:SCRNBASEADR
  159.                MOV            AL,32
  160. CLREOL:        MOV            [EBX],AL                      ;Clear to end of line
  161.                ADD            EBX,2
  162.                DEC            CL
  163.                JNZ            CLREOL
  164.                POP            EAX                           ;POP cursor position
  165.                INC            AH                            ;Increment row
  166.                CMP            AH,24
  167.                JA             DOSCROLL
  168.                XOR            AL,AL                         ;Set column to zero
  169.                MOV            WORD PTR DS:[CURPOSADR],AX
  170. EXIT:          POP            ECX
  171.                POP            EBX
  172.                POP            EAX
  173.                RET
  174. DOSCROLL:      PUSHD          OFFSET EXIT
  175.                JMP            SCRLUP
  176. CRLF           ENDP
  177.  
  178. ;Scroll entire screen up one line and leave cursor at start of line 24.
  179. SCRLUP         PROC NEAR
  180.                PUSH           EAX
  181.                PUSH           EBX
  182.                PUSH           ECX
  183.                MOV            EBX,CS:SCRNBASEADR
  184.                MOV            ECX,960                       ;960 = (80*24*2)/4 (DWORDS to scroll)
  185. SCROLLLOOP:    MOV            EAX,[EBX+160]
  186.                MOV            [EBX],EAX
  187.                ADD            EBX,4
  188.                DEC            ECX
  189.                JNZ            SCROLLLOOP
  190.                MOV            CL,80
  191.                MOV            AL,32
  192. CLR24:         MOV            [EBX],AL                      ;Clear line 24
  193.                ADD            EBX,2
  194.                DEC            CL
  195.                JNZ            CLR24
  196. EXIT:          MOV            WORD PTR DS:[CURPOSADR],1800H ;Set cursor to bottom line in zero column
  197.                POP            ECX
  198.                POP            EBX
  199.                POP            EAX
  200.                RET
  201. SCRLUP         ENDP
  202.  
  203. ;Print AL spaces at cursor.
  204. SPC            PROC NEAR
  205.                OR             AL,AL
  206.                JZ             EXIT
  207.                PUSH           EAX
  208.                MOV            AH,AL
  209.                MOV            AL,32
  210. PRINTSPC:      CALL           PCH
  211.                DEC            AH
  212.                JNZ            PRINTSPC
  213.                POP            EAX
  214. EXIT:          RET
  215. SPC            ENDP
  216.  
  217. ;Clear screen and leave cursor at (0,0) position.
  218. CLS            PROC NEAR
  219.                PUSH           EAX
  220.                PUSH           EBX
  221.                PUSH           ESI
  222.                MOV            EBX,CS:SCRNBASEADR
  223.                MOV            ESI,1999
  224.                MOV            AL,32
  225. DOCLS:         MOV            [EBX+2*ESI],AL
  226.                DEC            ESI
  227.                JNS            DOCLS
  228.                MOV            WORD PTR DS:[CURPOSADR],0H
  229.                POP            ESI
  230.                POP            EBX
  231.                POP            EAX
  232.                RET
  233. CLS            ENDP
  234.  
  235. ;Print ASCIIZ string at address in ES:EBX.
  236. PSTR           PROC NEAR
  237.                PUSH           EAX
  238.                PUSH           EBX
  239. CHARLOOP:      MOV            AL,ES:[EBX]
  240.                OR             AL,AL                         ;See if at end of string
  241.                JZ             EXIT
  242.                CALL           PCH
  243.                INC            EBX
  244.                JMP            CHARLOOP
  245. EXIT:          POP            EBX
  246.                POP            EAX
  247.                RET
  248. PSTR           ENDP
  249.  
  250. ;Print ASCIIZ string at address CS:EBX.
  251. PCSSTR         PROC NEAR
  252.                PUSH           EAX
  253.                PUSH           EBX
  254. CHARLOOP:      MOV            AL,CS:[EBX]                   ;See if at end of string
  255.                OR             AL,AL
  256.                JZ             EXIT
  257.                CALL           PCH
  258.                INC            EBX
  259.                JMP            CHARLOOP
  260. EXIT:          POP            EBX
  261.                POP            EAX
  262.                RET
  263. PCSSTR         ENDP
  264.  
  265. ;Print hexadecimal WORD in AX.
  266. PHW            PROC NEAR
  267.                PUSH           EAX
  268.                PUSH           ECX
  269.                PUSH           EDX
  270.                MOV            EDX,EAX
  271.                MOV            CL,4                          ;Print four nibbles
  272. CALCNIBS:      MOV            AL,DL
  273.                AND            AL,0FH
  274.                ADD            AL,48
  275.                CMP            AL,57
  276.                JBE            PUSHDIGIT
  277.                ADD            AL,7
  278. PUSHDIGIT:     PUSH           EAX
  279.                SHR            EDX,4
  280.                DEC            CL
  281.                JNZ            CALCNIBS
  282.                MOV            CL,4
  283. PRNTNIBS:      POP            EAX
  284.                CALL           PCH
  285.                DEC            CL
  286.                JNZ            PRNTNIBS
  287.                POP            EDX
  288.                POP            ECX
  289.                POP            EAX
  290.                RET
  291. PHW            ENDP
  292.  
  293. ;Print hexadecimal DWORD in EAX.
  294. PHD            PROC NEAR
  295.                PUSH           EAX
  296.                PUSH           ECX
  297.                PUSH           EDX
  298.                MOV            EDX,EAX
  299.                MOV            CL,8                          ;Print eight nibbles
  300. CALCNIBS:      MOV            AL,DL
  301.                AND            AL,0FH
  302.                ADD            AL,48
  303.                CMP            AL,57
  304.                JBE            PUSHDIGIT
  305.                ADD            AL,7
  306. PUSHDIGIT:     PUSH           EAX
  307.                SHR            EDX,4
  308.                DEC            CL
  309.                JNZ            CALCNIBS
  310.                MOV            CL,8
  311. PRNTNIBS:      POP            EAX
  312.                CALL           PCH
  313.                DEC            CL
  314.                JNZ            PRNTNIBS
  315.                POP            EDX
  316.                POP            ECX
  317.                POP            EAX
  318.                RET
  319. PHD            ENDP
  320.  
  321. ;Print unsigned WORD in AX as decimal.
  322. PUW            PROC NEAR
  323.                PUSH           EAX
  324.                PUSH           EBX
  325.                PUSH           ECX
  326.                PUSH           EDX
  327.                AND            EAX,0FFFFH
  328.                XOR            ECX,ECX
  329.                MOV            EBX,10
  330. CALCDIGS:      XOR            EDX,EDX
  331.                DIV            BX
  332.                PUSH           EDX
  333.                INC            ECX
  334.                OR             EAX,EAX
  335.                JNZ            CALCDIGS
  336. PRNTDIGS:      POP            EAX
  337.                ADD            AL,48
  338.                CALL           PCH
  339.                DEC            ECX
  340.                JNZ            PRNTDIGS
  341.                POP            EDX
  342.                POP            ECX
  343.                POP            EBX
  344.                POP            EAX
  345.                RET
  346. PUW            ENDP
  347.  
  348. ;Print unsigned DWORD in EAX as decimal.
  349. PUD            PROC NEAR
  350.                PUSH           EAX
  351.                PUSH           EBX
  352.                PUSH           ECX
  353.                PUSH           EDX
  354.                XOR            ECX,ECX
  355.                MOV            EBX,10
  356. CALCDIGS:      XOR            EDX,EDX
  357.                DIV            EBX
  358.                PUSH           EDX
  359.                INC            ECX
  360.                OR             EAX,EAX
  361.                JNZ            CALCDIGS
  362. PRNTDIGS:      POP            EAX
  363.                ADD            AL,48
  364.                CALL           PCH
  365.                DEC            ECX
  366.                JNZ            PRNTDIGS
  367.                POP            EDX
  368.                POP            ECX
  369.                POP            EBX
  370.                POP            EAX
  371.                RET
  372. PUD            ENDP
  373.  
  374. ;Print signed WORD in AX as decimal.
  375. PSW            PROC NEAR
  376.                PUSH           EAX
  377.                OR             AX,AX
  378.                JNS            PABS
  379.                PUSH           EAX
  380.                MOV            AL,"-"
  381.                CALL           PCH
  382.                POP            EAX
  383.                NEG            AX                            ;Calculate absolute value
  384. PABS:          CALL           PUW                           ;Print absolute value
  385.                POP            EAX
  386.                RET
  387. PSW            ENDP
  388.  
  389. ;Print signed DWORD in EAX as decimal.
  390. PSD            PROC NEAR
  391.                PUSH           EAX
  392.                OR             EAX,EAX
  393.                JNS            PABS
  394.                PUSH           EAX
  395.                MOV            AL,"-"
  396.                CALL           PCH
  397.                POP            EAX
  398.                NEG            EAX                           ;Calculate absolute value
  399. PABS:          CALL           PUD                           ;Print absolute value
  400.                POP            EAX
  401.                RET
  402. PSD            ENDP
  403.  
  404. ;Print ST of FPU using format code in AX.  Call with lowest seven bits of AH =
  405. ;number of high-order digits plus the sign (if negative), and lowest five bits
  406. ;of AL = number of low-order digits.  Fractions are printed with leading zeros
  407. ;if the sign bit of AH is clear.  Will print numbers absolutely smaller than
  408. ;10 ^ 18 and will print up to 18 decimal places.  Will fill entire print field
  409. ;with "*" if high-order digit field is too small.  Will fill entire print field
  410. ;with ">" if number is absolutely greater than or equal to 10 ^ 18.  It is
  411. ;assumed that ST contains a valid number.  AL must not be greater than 18.
  412. FPST           PROC NEAR
  413.                LOCAL NOLEAD0FLAG:DWORD                      ;If set, then no leading zero is placed in front of fractions
  414.                LOCAL FLDWIDTH:DWORD                         ;The width of the print field
  415.                LOCAL NOHIDIGITS:DWORD                       ;Number of high-order digits
  416.                LOCAL NOLODIGITS:DWORD                       ;Number of low-order digits
  417.                LOCAL OLDCWORD:WORD                          ;Old FPU control word
  418.                LOCAL NEWCWORD:WORD                          ;Local FPU control word
  419.                LOCAL HIDIGITS[10]:BYTE                      ;Storage for high-order digit string
  420.                LOCAL LODIGITS[10]:BYTE                      ;Storage for low-order digit string
  421.                PUSH           EAX
  422.                PUSH           EBX
  423.                PUSH           ECX
  424.                PUSH           EDX
  425.                PUSH           ESI
  426.                PUSH           EDI
  427.                XOR            ECX,ECX                       ;Assume leading zeros on fractions
  428. CHKLEADZERO:   OR             AH,AH                         ;Test assumption
  429.                JNS            SETLEAD0MODE
  430.                INC            ECX                           ;Will not print leading zeros
  431. SETLEAD0MODE:  MOV            NOLEAD0FLAG,ECX
  432.                AND            AH,7FH                        ;Mask leading zero flag
  433.                MOV            CL,AH                         ;Set ECX = number of high order digits + sign
  434.                MOV            NOHIDIGITS,ECX
  435.                MOV            CL,AL                         ;Set ECX = number of decimal places
  436.                MOV            NOLODIGITS,ECX
  437.                ADD            AL,AH                         ;Compute field width in EAX
  438.                AND            EAX,0FFH
  439.                OR             ECX,ECX
  440.                JZ             SETFLDWIDTH
  441.                INC            EAX                           ;Account for decimal point
  442. SETFLDWIDTH:   MOV            FLDWIDTH,EAX
  443.                FSTCW          OLDCWORD                      ;Save original control word
  444.                MOV            AX,OLDCWORD
  445.                OR             AH,0FH                        ;Set PC to 64 bits and RC to truncate
  446.                MOV            NEWCWORD,AX
  447.                FLDCW          NEWCWORD
  448.                FLD            ST                            ;See if number of high order digits greater than 18
  449.                FABS
  450.                FCOM           CS:FPPOWERTEN[8*18]
  451.                FSTSW          AX
  452.                SAHF
  453.                JAE            OVERFLOW
  454.                FLD            ST(1)                         ;Compute and save high order digits
  455.                FBSTP          TBYTE PTR HIDIGITS[0]
  456.                FLD            ST                            ;Compute and save low order digits
  457.                FRNDINT
  458.                AND            BYTE PTR NEWCWORD[1],0F3H     ;Set RC to round
  459.                FLDCW          NEWCWORD
  460.                FSUB
  461.                FMUL           CS:FPPOWERTEN[8*ECX]
  462. CALCLODIGITS:  XOR            EAX,EAX
  463.                XOR            EDI,EDI
  464.                MOV            ESI,8
  465.                FBSTP          TBYTE PTR LODIGITS[0]
  466. GETHIDIGIT:    OR             AL,HIDIGITS[ESI]              ;Find first nonzero digit
  467.                JNZ            CALCHIORDER
  468.                DEC            ESI
  469.                JNS            GETHIDIGIT
  470.                XOR            ESI,ESI                       ;There are no nonzero high order digits
  471.                TEST           BYTE PTR NOLEAD0FLAG[0],01H   ;See if leading zeros are disabled
  472.                JNZ            CHKSIGN
  473.                INC            ESI                           ;Add leading zero
  474.                JMP            CHKSIGN
  475. CALCHIORDER:   MOV            EDI,ESI
  476.                INC            ESI                           ;Convert ESI to number of high order digits
  477.                ADD            ESI,ESI
  478.                AND            AL,0F0H                       ;See if highest digit is in odd position
  479.                JNZ            CHKSIGN
  480.                DEC            ESI
  481. CHKSIGN:       MOV            DL,HIDIGITS[9]                ;Get sign byte
  482.                OR             DL,DL
  483.                JNS            CHKHIFLD
  484.                INC            ESI                           ;Account for "-"
  485. CHKHIFLD:      MOV            EAX,NOHIDIGITS
  486.                SUB            EAX,ESI                       ;See if field for high-order digits and sign is large enough
  487.                JB             SMALLFLD
  488.                CALL           SPC                           ;Print leading spaces
  489. PRNTSIGN:      OR             DL,DL
  490.                JNS            PRNTHIDIGITS
  491.                MOV            AL,"-"
  492.                CALL           PCH
  493.                DEC            ESI
  494. PRNTHIDIGITS:  OR             ESI,ESI                       ;See if any high order digits are to be printed
  495.                JZ             PRNTDEC
  496.                MOV            DL,HIDIGITS[EDI]
  497.                TEST           ESI,01H
  498.                JNZ            ODDHIDIGIT
  499. HIDIGITLOOP:   MOV            AL,DL
  500.                SHR            AL,4
  501.                ADD            AL,48
  502.                CALL           PCH
  503. ODDHIDIGIT:    MOV            AL,DL
  504.                AND            AL,0FH
  505.                ADD            AL,48
  506.                CALL           PCH
  507.                DEC            EDI
  508.                JS             PRNTDEC
  509.                MOV            DL,HIDIGITS[EDI]
  510.                JMP            HIDIGITLOOP
  511. PRNTDEC:       OR             ECX,ECX                       ;See if any low order digits are to be printed
  512.                JZ             EXIT
  513.                MOV            AL,"."
  514.                CALL           PCH
  515.                MOV            EDI,ECX                       ;Find byte number for first digit
  516.                DEC            EDI
  517.                SHR            EDI,1
  518.                MOV            DL,LODIGITS[EDI]
  519.                TEST           CL,01H
  520.                JNZ            ODDLODIGIT
  521. LODIGITLOOP:   MOV            AL,DL
  522.                SHR            AL,4
  523.                ADD            AL,48
  524.                CALL           PCH
  525. ODDLODIGIT:    MOV            AL,DL
  526.                AND            AL,0FH
  527.                ADD            AL,48
  528.                CALL           PCH
  529.                DEC            EDI
  530.                JS             EXIT
  531.                MOV            DL,LODIGITS[EDI]
  532.                JMP            LODIGITLOOP
  533. EXIT:          FLDCW          OLDCWORD                      ;Restore calling control word
  534.                POP            EDI
  535.                POP            ESI
  536.                POP            EDX
  537.                POP            ECX
  538.                POP            EBX
  539.                POP            EAX
  540.                RET
  541. FILLFLD:       MOV            ECX,FLDWIDTH
  542. RCDCHAR:       CALL           PCH                           ;Print one character even if field width is zero
  543.                SUB            ECX,1
  544.                JAE            RCDCHAR
  545.                JMP            EXIT
  546. SMALLFLD:      MOV            AL,"*"
  547.                JMP            FILLFLD
  548. OVERFLOW:      FSTP           ST                            ;Pop absolute value of number
  549.                MOV            AL,">"
  550.                JMP            FILLFLD
  551.                ALIGN          8
  552. FPPOWERTEN     LABEL QWORD
  553.                DQ             1.0E0
  554.                DQ             1.0E1
  555.                DQ             1.0E2
  556.                DQ             1.0E3
  557.                DQ             1.0E4
  558.                DQ             1.0E5
  559.                DQ             1.0E6
  560.                DQ             1.0E7
  561.                DQ             1.0E8
  562.                DQ             1.0E9
  563.                DQ             1.0E10
  564.                DQ             1.0E11
  565.                DQ             1.0E12
  566.                DQ             1.0E13
  567.                DQ             1.0E14
  568.                DQ             1.0E15
  569.                DQ             1.0E16
  570.                DQ             1.0E17
  571.                DQ             1.0E18
  572. FPST           ENDP
  573.  
  574. ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  575. ;Keyboard Routines
  576. ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  577.  
  578. ;Get chracter from keyboard without echo.  Return ASCII code or scan code in AL.
  579. ;The sign bit of AH is set if a scan code.  The state of the shift keys is also
  580. ;in AH.  Bits of AH are defined: 0 = shift, 1 = ctrl, 2 = alt, 3 = scroll lock,
  581. ;4 = num lock, 5 = caps lock, 6 = insert.  The high word of EAX is cleared.
  582. ;Interrupts must be enabled.
  583. GETCH          PROC NEAR
  584.                PUSH           EDX
  585.                MOV            AH,10H                        ;Remove key from type-ahead buffer.  Will wait if no key present
  586.                INT            16H                           ;Scan code in AH, ASCII code in AL
  587.                MOV            EDX,EAX
  588.                MOV            AH,12H                        ;Get state of flags
  589.                INT            16H
  590.                TEST           AL,01H                        ;Combine right and left shift keys
  591.                JZ             FIXFLAGS
  592.                OR             AL,02H
  593. FIXFLAGS:      SHR            AL,1
  594.                AND            EAX,07FH
  595.                MOV            AH,AL
  596.                MOV            AL,DL                         ;Put ASCII scan code in AL
  597.                CMP            AL,0E0H                       ;See if the character is for non-ASCII enhanced keyboard key
  598.                JE             DOSCAN
  599.                OR             AL,AL                         ;See if the character is for a non-ASCII key
  600.                JNZ            EXIT
  601. DOSCAN:        MOV            AL,DH                         ;Put scan code in AL
  602.                OR             AH,80H                        ;Set high bit to denote scan code
  603. EXIT:          POP            EDX
  604.                RET
  605. GETCH          ENDP
  606.  
  607. ;Set cursor position at (row,col) = (AH,AL).
  608. SETCSRPOS      PROC NEAR
  609.                PUSH           EAX
  610.                PUSH           EBX
  611.                PUSH           EDX
  612.                CMP            AH,24                         ;Do not allow row greater than 24
  613.                JBE            CHKCOL
  614.                MOV            AH,24
  615. CHKCOL:        CMP            AL,79                         ;Do not allow column greater than 79
  616.                JBE            SETCURSOR
  617.                MOV            AL,79
  618. SETCURSOR:     MOV            EDX,EAX                       ;Place coordinates in DX
  619.                XOR            EBX,EBX                       ;Use screen zero
  620.                MOV            AH,02H                        ;Function to set cursor position
  621.                INT            10H
  622.                POP            EDX
  623.                POP            EBX
  624.                POP            EAX
  625.                RET
  626. SETCSRPOS      ENDP
  627.  
  628. ;Get cursor position in (AH,AL) = (row,col)
  629. GETCSRPOS      PROC NEAR
  630.                PUSH           EBX
  631.                PUSH           ECX
  632.                PUSH           EDX
  633.                MOV            AH,03H                        ;Function to get cursor position
  634.                XOR            EBX,EBX                       ;Get position for screen zero
  635.                INT            10H                           ;Cursor position returned in DX, and type returned in CX
  636.                MOV            EAX,EDX
  637.                POP            EDX
  638.                POP            ECX
  639.                POP            EBX
  640.                RET
  641. GETCSRPOS      ENDP
  642.  
  643. ;Physically relocate the cursor on the screen to the current BIOS coordinates.
  644. UPDATECSR      PROC NEAR
  645.                PUSHD          OFFSET SETCSRPOS
  646.                JMP            GETCSRPOS
  647. UPDATECSR      ENDP
  648.  
  649. ;Set cursor type.  Call with AL = 1 for block, AL = 0 for underline, and sign
  650. ;bit of AL set to disable.
  651. SETCSRTYPE     PROC NEAR
  652.                PUSH           EAX
  653.                PUSH           ECX
  654.                MOV            AH,01H
  655.                MOV            CX,0607H                      ;Assume underline cursor
  656.                OR             AL,AL
  657.                JZ             SETCURLINES
  658.                JS             DISABLECSR
  659.                XOR            CH,CH                         ;Set to block cursor
  660.                JMP            SETCURLINES
  661. DISABLECSR:    MOV            CH,20H                        ;Disable cursor
  662. SETCURLINES:   INT            10H
  663.                POP            ECX
  664.                POP            EAX
  665.                RET
  666. SETCSRTYPE     ENDP
  667.  
  668. ;Get cursor position and type.  Position in DX and type in CX.
  669. GETCSR         PROC NEAR
  670.                PUSH           EAX
  671.                PUSH           EBX
  672.                MOV            AH,03H                        ;Function to get cursor position
  673.                XOR            EBX,EBX                       ;BH = page
  674.                INT            10H                           ;(start,end) scan line for cursor in (CH,CL)
  675.                POP            EBX                           ;(row/column) for cursor in (DH,DL)
  676.                POP            EAX
  677.                RET
  678. GETCSR         ENDP
  679.  
  680. ;Set cursor position and type.  Call with (DH,DL) = (row,col) for cursor and
  681. ;(CH,CL) = (start,end) scan line for cursor.
  682. SETCSR         PROC NEAR
  683.                PUSH           EAX
  684.                PUSH           EBX
  685.                MOV            AH,02H                        ;Set cursor position
  686.                XOR            EBX,EBX                       ;Use page zero
  687.                INT            10H
  688.                DEC            AH                            ;Set cursor type
  689.                INT            10H
  690.                POP            EBX
  691.                POP            EAX
  692.                RET
  693. SETCSR         ENDP
  694.  
  695. ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  696. ;Speaker Routines
  697. ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  698.  
  699. ;Produce beep through speaker.  Interrupts must be enabled.
  700. BEEP           PROC NEAR
  701.                PUSH           EAX
  702.                PUSH           EDX
  703.                IN             AL,61H
  704.                MOV            DX,6818                       ;175 cycles/second
  705.                CALL           SOUND
  706.                MOV            EDX,TICKCNTADR                ;Hold sound for four ticks
  707.                PUSH           EAX
  708.                MOV            EAX,[EDX]
  709.                ADD            EAX,4
  710. DELAY:         CMP            [EDX],EAX                     ;Will hang in this loop timer-tick interrupt not enabled
  711.                JNE            DELAY
  712.                POP            EAX                           ;Disable sound
  713.                OUT            61H,AL
  714.                POP            EDX
  715.                POP            EAX
  716.                RET
  717. BEEP           ENDP
  718.  
  719. ;Activate speaker.  Call with frequency divisor in DX.  Divisor = 1,193,180
  720. ;divided by cycles per second.
  721. SOUND          PROC NEAR
  722.                PUSH           EAX
  723.                MOV            AL,10110110B                  ;Channel 2, LSB/MSB, mode 3, binary
  724.                OUT            43H,AL                        ;Program the timer
  725.                MOV            EAX,EDX
  726.                OUT            42H,AL
  727.                MOV            AL,AH
  728.                OUT            42H,AL
  729.                IN             AL,61H
  730.                OR             AL,03H                        ;Enable speaker and use channel 2 for input
  731.                OUT            61H,AL
  732.                POP            EAX
  733.                RET
  734. SOUND          ENDP
  735.